Introducción

La relación entre la salud mental y el empleo, especialmente en los trabajos que nos llevan a pasar muchas horas frente a un ordenador, ha cobrado una importancia creciente en los últimos años debido al aumento de casos de ansiedad, episodios depresivos y estrés laboral, así como otro tipo de enfermedades mentales entre los profesionales de los diferentes sectores. Nuestro seminario aborda este vínculo.

Buscamos analizar cómo el aislamiento social, la falta de contacto humano, la monotonía y la dificultad para separar la vida laboral de la personal contribuyen a deteriorar el bienestar emocional de las personas que trabajan en espacios confinados. Además, queremos comprender por qué estos factores pueden desencadenar problemas como ansiedad, estrés, depresión y trastornos del sueño, y cómo el entorno laboral puede influir en la aparición y agravamiento de estos síntomas.

Objetivos

Objetivo General

Demostrar si es que existe, la relación entre episodios depresivos y el teletrabajo, en la actualidad.

Objetivos Específicos

  1. Analizar la relación entre el porcentaje de teletrabajo en las comunidades autónomas de España y los indicadores de salud mental de su población.

  2. Evaluar si existen diferencias significativas en la prevalencia de problemas de salud mental entre las Islas Canarias y el conjunto de España en función de la tasa de teletrabajo por provincia o comunidad autónoma.

Metodología y Resultados

A continuacion cargamos las siguientes librerias

library(tidyverse) 
library(readr)    


library(rjson)
library(tidyjson)

library(ggplot2)   # Gráficos estáticos
library(plotly)    # Gráficos interactivos
library(DT)        # Tablas interactivas
library(mapSpain)  # Para los mapas
library(gganimate)

Cargamos los archivos

Ahora, vamos a leer los archivos. Los datos los hemos recopilado de páginas estatales como el Instituto Nacional de Estadística y “datos.gob” así como de la página estatal del Instituto Canario de Estadística (instac).

Cargamos el primer archivo episodios depresivos.csv

Necesitamos cargar el archivo episodios depresivos.csv.

# Cargamos el archivo CSV de episodios depresivos

depresion_raw <- read_delim(
  "input/data/episodios_depresivos.csv",
  delim = ";",
  escape_double = FALSE,
  trim_ws = TRUE,
  locale = locale(encoding = "ISO-8859-1")
)
## Rows: 420 Columns: 5
## ── Column specification ────────────────────────────────────────────────────────
## Delimiter: ";"
## chr (5): Sexo, Total Nacional, Comunidades y Ciudades Autónomas, Intensidad ...
## 
## ℹ Use `spec()` to retrieve the full column specification for this data.
## ℹ Specify the column types or set `show_col_types = FALSE` to quiet this message.
# Mostramos la tabla para ver cómo ha salido
datatable(depresion_raw)

Cargamos el archivo teletrabajo_por_comunidad.csv

Necesitamos cargar el archivo teletrabajo_por_comunidad.csv.

teletrabajo_comunidad_raw <- read_delim(
  "input/data/teletrabajo_por_comunidad.csv",
  delim = ";",
  escape_double = FALSE,
  trim_ws = TRUE,
  locale = locale(encoding = "ISO-8859-1")
)
## Rows: 200 Columns: 5
## ── Column specification ────────────────────────────────────────────────────────
## Delimiter: ";"
## chr (5): Total Nacional, Comunidades y Ciudades Autónomas, Clase de població...
## 
## ℹ Use `spec()` to retrieve the full column specification for this data.
## ℹ Specify the column types or set `show_col_types = FALSE` to quiet this message.
datatable(teletrabajo_comunidad_raw)

Cargamos el archivo teletrabajoporporprovincias.csv

Necesitamos cargar el archivo teletrabajoporprovincias.csv.

teletrabajo_provincias_raw <- read_delim(
  "INPUT/DATA/teletrabajoporprovincias.csv",
  delim = ",",
  escape_double = FALSE,
  trim_ws = TRUE,
  locale = locale(encoding = "ISO-8859-1")
)
## Rows: 16 Columns: 5
## ── Column specification ────────────────────────────────────────────────────────
## Delimiter: ","
## chr (3): indicadores_nombre, islas_id, islas_nombre
## dbl (2): indicadores_id, teletrabajo_porcentaje_empresas_teletrabajadores_pe...
## 
## ℹ Use `spec()` to retrieve the full column specification for this data.
## ℹ Specify the column types or set `show_col_types = FALSE` to quiet this message.
datatable(teletrabajo_provincias_raw)

Cargamos el archivo JSON de datos de salud mental en Canarias

# Este es un proceso un poco diferente a cargar los csvs
# 1. Cargar el archivo JSON
json_data <- fromJSON(file = "input/data/saludmentalcanarias.json")

# 2. Extraer los valores numéricos
valores <- sapply(json_data$data, function(x) x$Valor)

# 3. Extraer los códigos (Isla, Tipo de dato, Estado mental)
codigos_list <- lapply(json_data$data, function(x) x$dimCodes)
codigos_matriz <- do.call(rbind, codigos_list)

# 4. Crear un Data Frame inicial 
df_sucio <- data.frame(
  Valor = as.numeric(valores),
  Codigo_Isla = codigos_matriz[, 1],   # Columna 1: Isla
  Codigo_Tipo = codigos_matriz[, 2],   # Columna 2: Absoluto/Porcentaje
  Codigo_Estado = codigos_matriz[, 3]  # Columna 3: Estado Mental
)

# 5.
# Leyenda de Islas
leyenda_islas <- data.frame(
  Codigo_Isla = json_data$categories[[1]]$codes,
  Nombre_Isla = json_data$categories[[1]]$labels
)

# Leyenda de Estados de Salud Mental
leyenda_estado <- data.frame(
  Codigo_Estado = json_data$categories[[3]]$codes,
  Descripcion_Estado = json_data$categories[[3]]$labels
)

# 6. Unir todo para tener la tabla final, usamos un left join
salud_mental_canarias <- df_sucio %>%
  left_join(leyenda_islas, by = "Codigo_Isla") %>%
  left_join(leyenda_estado, by = "Codigo_Estado") %>%
  # Filtramos para ver porcentajes y el estado "6 o más síntomas" (indicador de problema)
  filter(Codigo_Tipo == "Porcentaje") %>%
  select(Nombre_Isla, Descripcion_Estado, Valor)

datatable(salud_mental_canarias)

Limpieza de datos

Limpieza de episodios_depresivos.csv

# 1. Cargamos el archivo CON LA CODIFICACIÓN CORRECTA
depresion_raw <- read_delim("input/data/episodios_depresivos.csv", 
                            delim = ";", 
                            escape_double = FALSE, 
                            trim_ws = TRUE,
                            locale = locale(encoding = "ISO-8859-1"))

# 2. Limpiamos y calculamos porcentajes
depresion_intensidad <- depresion_raw %>%
  # Quitamos el Total Nacional
  filter(`Comunidades y Ciudades Autónomas` != "Total Nacional") %>%
  filter(!is.na(`Comunidades y Ciudades Autónomas`)) %>%
  
  # Convertimos a número
  mutate(
    Valor_Numerico = as.numeric(gsub(",", ".", gsub("\\.", "", Total)))
  ) %>%
  
  # Nos quedamos con "Ambos sexos"
  filter(Sexo == "Ambos sexos") %>% 
  
  # Calculamos el porcentaje
  group_by(`Comunidades y Ciudades Autónomas`) %>%
  mutate(
    Total_Poblacion = Valor_Numerico[`Intensidad depresión` == "TOTAL"],
    # ¡AQUÍ ESTÁ EL CAMBIO! Redondeamos a 2 decimales
    Porcentaje = round((Valor_Numerico / Total_Poblacion) * 100, 2)
  ) %>%
  ungroup() %>%
  
  # ELIMINAR TOTAL: Quitamos la fila que dice TOTAL
  filter(`Intensidad depresión` != "TOTAL") %>%
  
  # Limpiamos nombre de la comunidad
  mutate(
    Comunidad = trimws(gsub("^[0-9]+", "", `Comunidades y Ciudades Autónomas`))
  ) %>%
  
  # Seleccionamos columnas finales
  select(Comunidad, Intensidad = `Intensidad depresión`, Porcentaje)

# Mostramos la tabla
datatable(depresion_intensidad)

Gráfico que muestra los episodios depresivos de los habitantes de cada comunidad en España

# 1. Filtramos los datos para excluir la categoría "Ninguna" y "No consta"
depresion_con_sintomas <- depresion_intensidad %>%
  filter(!Intensidad %in% c("Ninguna", "No consta")) %>%
  
  # Ordenamos las comunidades por el porcentaje total de depresión para un gráfico limpio
  group_by(Comunidad) %>%
  mutate(Total_Depresion = sum(Porcentaje)) %>%
  ungroup() %>%
  arrange(desc(Total_Depresion)) %>%
  
  # Convertimos la comunidad a factor para mantener el orden en el gráfico
  mutate(Comunidad = factor(Comunidad, levels = unique(Comunidad)))

# 2. Creamos el gráfico de barras agrupadas
grafico_intensidad <- ggplot(depresion_con_sintomas, 
                             aes(x = Comunidad, y = Porcentaje, fill = Intensidad)) +
  
  # Usamos barras con posición dodged (agrupadas lado a lado)
  geom_bar(stat = "identity", position = position_dodge(width = 0.8), width = 0.7) +
  
  # Personalizamos colores
  scale_fill_brewer(palette = "Reds", direction = -1, 
                    name = "Intensidad",
                    # Aseguramos que la leyenda vaya en orden de severidad
                    breaks = c("Grave", "Moderadamente grave", "Moderada", "Leve")) +
  
  # Giramos las coordenadas para que los nombres de las CCAA sean legibles
  coord_flip() +
  
  labs(
    title = "Prevalencia y Severidad de Episodios Depresivos por CCAA",
    subtitle = "El porcentaje es sobre el total de la población de cada Comunidad.",
    x = "", # Dejamos el eje X (Comunidades) vacío tras el flip
    y = "Porcentaje de Población (%)"
  ) +
  theme_minimal() +
  theme(legend.position = "bottom")

# Hacemos el gráfico interactivo
ggplotly(grafico_intensidad)

Limpieza de teletrabajo_por_comunidad

# 2. Limpiamos para tener SOLO una fila por Comunidad (Trabajadores que teletrabajan)
teletrabajo_ocupados <- teletrabajo_comunidad_raw %>%
  # Quitamos Total Nacional y vacíos
  filter(`Comunidades y Ciudades Autónomas` != "Total Nacional") %>%
  filter(!is.na(`Comunidades y Ciudades Autónomas`)) %>%
  
  # FILTRO CLAVE: Nos quedamos SOLO con el grupo de "Personas ocupadas"
  filter(`Clase de población` == "Personas ocupadas") %>%
  
  # Nos quedamos con los que SÍ teletrabajan
  filter(Teletrabajo == "Personas que han teletrabajado") %>%
  
  # Limpiamos el nombre de la Comunidad
  mutate(
    Comunidad = trimws(gsub("^[0-9]+", "", `Comunidades y Ciudades Autónomas`))
  ) %>%
  
  # Convertimos el porcentaje a número
  mutate(
    Porcentaje_Teletrabajo_Ocupados = as.numeric(gsub(",", ".", Total))
  ) %>%
  
  # Seleccionamos solo Nombre y Porcentaje
  select(Comunidad, Porcentaje_Teletrabajo_Ocupados)

# Mostramos la tabla (ahora sí, 1 sola fila por CCAA)
datatable(teletrabajo_ocupados)

Gráfico que muestra porcentajes de teletrabajo de los habitantes de cada comunidad en España

# 1. Creamos el gráfico de barras horizontal
grafico_teletrabajo <- ggplot(teletrabajo_ocupados, 
                              aes(x = Porcentaje_Teletrabajo_Ocupados, 
                                  # Ordenamos las CCAA de menor a mayor porcentaje
                                  y = reorder(Comunidad, Porcentaje_Teletrabajo_Ocupados))) +
  
  geom_col(aes(fill = Porcentaje_Teletrabajo_Ocupados), width = 0.8) +
  
  # Añadimos etiquetas con el porcentaje exacto al final de cada barra
  geom_text(aes(label = paste0(Porcentaje_Teletrabajo_Ocupados, "%")), 
            hjust = -0.1, size = 3) + 
  
  scale_fill_gradient(low = "#b2e2e2", high = "#225ea8", name = "Porcentaje") +
  
  labs(
    title = "Penetración del Teletrabajo en la Población Ocupada por CCAA",
    subtitle = "El porcentaje es sobre el total de personas con empleo.",
    x = "Porcentaje de Teletrabajadores (%)",
    y = "" # Dejamos el eje Y vacío para que solo se vea el nombre de la CCAA
  ) +
  theme_minimal() +
  theme(
    legend.position = "none", # La leyenda ya no es necesaria
    panel.grid.major.y = element_blank() # Quitamos las líneas horizontales
  )

# Hacemos el gráfico interactivo
ggplotly(grafico_teletrabajo)

Limpieza de teletrabajoporprovincias

# 2. Limpiamos y filtramos
teletrabajo_personal_canarias <- teletrabajo_provincias_raw%>%
  # A. FILTRO IMPORTANTE: Nos quedamos solo con el indicador de "PERSONAL TOTAL"
  filter(indicadores_nombre == "Porcentaje del personal total que es teletrabajador") %>%
  
  # B. Quitamos el total de "Canarias" para ver solo las islas
  filter(islas_nombre != "Canarias") %>%
  
  # C. Creamos la columna PROVINCIA (asignando cada isla a la suya)
  mutate(
    Provincia = case_when(
      islas_nombre %in% c("Gran Canaria", "Lanzarote", "Fuerteventura") ~ "Las Palmas",
      islas_nombre %in% c("Tenerife", "La Palma", "La Gomera", "El Hierro") ~ "S.C. Tenerife",
      TRUE ~ "Otra"
    )
  ) %>%
  
  # D. Seleccionamos y renombramos las columnas finales
  select(
    Provincia,
    Isla = islas_nombre, 
    Porcentaje_Personal_Teletrabajador = teletrabajo_porcentaje_empresas_teletrabajadores_personal_trabajaba_fuera_locales_empresa
  ) %>%
  
  # Ordenamos por provincia
  arrange(Provincia)

# Mostramos la tabla
datatable(teletrabajo_personal_canarias)

Grafica sobre el teletrabajo centrándonos en las Islas canarias

# 1. Creamos el gráfico de barras horizontal agrupado por Provincia
grafico_teletrabajo_islas <- ggplot(teletrabajo_personal_canarias, 
                              aes(x = Porcentaje_Personal_Teletrabajador, 
                                  # Ordenamos las islas de menor a mayor teletrabajo dentro de cada provincia
                                  y = reorder(Isla, Porcentaje_Personal_Teletrabajador))) +
  
  # Usamos el color de la barra para diferenciar la Provincia
  geom_col(aes(fill = Provincia), width = 0.7) +
  
  # Añadimos etiquetas con el porcentaje exacto
  geom_text(aes(label = paste0(Porcentaje_Personal_Teletrabajador, "%")), 
            hjust = -0.1, size = 3) + 
  
  # Separamos el gráfico en dos paneles (facetas) por Provincia
  facet_wrap(~ Provincia, scales = "free_y", ncol = 1) + # scales="free_y" ajusta las etiquetas de las Islas a cada panel
  
  scale_fill_manual(values = c("Las Palmas" = "#1b9e77", "S.C. Tenerife" = "#d95f02")) +
  
  labs(
    title = "Porcentaje de Personal Teletrabajador en las Islas Canarias",
    subtitle = "Comparación por Isla y Provincia.",
    x = "Porcentaje de Personal Teletrabajador (%)",
    y = ""
  ) +
  theme_minimal() +
  theme(
    legend.position = "none",
    panel.grid.major.y = element_blank(),
    strip.text = element_text(face = "bold") # Hace que el título de la provincia sea negrita
  )

# Hacemos el gráfico interactivo
ggplotly(grafico_teletrabajo_islas)

Limpieza de saludmentalcanaria.json

# 2. Extracción de valores y códigos
valores <- sapply(json_data$data, function(x) x$Valor)
codigos_list <- lapply(json_data$data, function(x) x$dimCodes)
codigos_matriz <- do.call(rbind, codigos_list)

# 3. Descifrar los NOMBRES (Leyendas)
leyenda_islas <- data.frame(
  Codigo_Isla = json_data$categories[[1]]$codes,
  Nombre_Isla = trimws(json_data$categories[[1]]$labels) 
)
leyenda_estado <- data.frame(
  Codigo_Estado = json_data$categories[[3]]$codes,
  Descripcion_Estado = trimws(json_data$categories[[3]]$labels)
)

# 4. LIMPIEZA FINAL Y UNIÓN
salud_mental_final <- data.frame(
  Valor = as.numeric(valores),
  Codigo_Isla = codigos_matriz[, 1],
  Codigo_Tipo = codigos_matriz[, 2],
  Codigo_Estado = codigos_matriz[, 3]
) %>%
  left_join(leyenda_islas, by = "Codigo_Isla") %>%
  left_join(leyenda_estado, by = "Codigo_Estado") %>%
  
  # FILTRO 1: Nos quedamos solo con PORCENTAJES
  filter(Codigo_Tipo == "Porcentaje") %>%
  
  # --- FILTRO CORREGIDO --- 
  # Eliminamos cualquier etiqueta que contenga un guion "-" (que indica sub-región)
  # y eliminamos el total "CANARIAS".
  filter(!str_detect(Nombre_Isla, "-|CANARIAS")) %>%
  # ------------------------
  
  # CREAMOS LA COLUMNA PROVINCIA
  mutate(
    Provincia = case_when(
      Nombre_Isla %in% c("Lanzarote", "Fuerteventura", "Gran Canaria") ~ "Las Palmas",
      Nombre_Isla %in% c("Tenerife", "La Palma", "La Gomera", "El Hierro") ~ "S.C. Tenerife",
      TRUE ~ "Otra"
    )
  ) %>%
  
  # Seleccionamos las columnas finales
  select(Provincia, Isla = Nombre_Isla, Estado_Mental = Descripcion_Estado, Porcentaje = Valor) %>%
  arrange(Provincia, Isla)

# Mostramos la tabla limpia
datatable(salud_mental_final)

Grafica sobre la salud mental centrándonos en las Islas canarias

# 1. ORDENACIÓN: Ordenamos las Islas por su porcentaje de riesgo más alto para un gráfico limpio
salud_mental_ordenada <- salud_mental_final %>%
  filter(Estado_Mental == "6 o más") %>%
  arrange(desc(Porcentaje)) %>%
  pull(Isla)

# 2. Creamos el gráfico de barras apiladas
grafico_salud_intensidad <- ggplot(salud_mental_final, 
                                     aes(x = Porcentaje, 
                                         # Usamos el factor ordenado para la Islas
                                         y = factor(Isla, levels = rev(salud_mental_ordenada)), 
                                         # Rellenamos con el estado mental (la pila)
                                         fill = Estado_Mental)) +
  
  geom_bar(stat = "identity", position = "stack", width = 0.8) +
  
  # Usamos facet_wrap para separar el análisis por Provincia
  facet_wrap(~ Provincia, scales = "free_y", ncol = 1) +
  
  # Colores: Usamos una escala que va de azul/verde (saludable) a rojo (riesgo)
  scale_fill_manual(
    name = "Síntomas de Mala Salud Mental",
    values = c("0" = "#a1d99b", "1" = "#edf8e9", "2" = "#fed98e", "3" = "#fe9929", "4" = "#d95f0e", "5" = "#993404", "6 o más" = "#7f0000"),
    breaks = c("0", "1", "2", "3", "4", "5", "6 o más", "No consta") # Ordenamos la leyenda
  ) +
  
  labs(
    title = "Perfiles de Salud Mental en las Islas Canarias",
    subtitle = "Distribución del porcentaje de la población según el número de síntomas (0 a 6 o más).",
    x = "Porcentaje de Población (%)",
    y = "Isla"
  ) +
  theme_minimal() +
  theme(
    legend.position = "bottom",
    panel.grid.major.y = element_blank(),
    strip.text = element_text(face = "bold")
  )

# Hacemos el gráfico interactivo
ggplotly(grafico_salud_intensidad)

Relacion entre teletrabajo y salud mental en España por comunidades

# 1. Agregamos el porcentaje de depresión por CCAA
# Sumamos todos los porcentajes, excluyendo "Ninguna" y "No consta"
depresion_agregada <- depresion_intensidad %>%
  filter(!Intensidad %in% c("Ninguna", "No consta")) %>%
  group_by(Comunidad) %>%
  summarise(
    Porcentaje_Con_Depresion = sum(Porcentaje, na.rm = TRUE),
    .groups = 'drop'
  )

# 2. Unimos los datos de Depresión y Teletrabajo por la columna "Comunidad"
datos_finales_obj1 <- left_join(depresion_agregada, teletrabajo_ocupados, by = "Comunidad")

# 3. Mostramos la tabla final unida
datatable(datos_finales_obj1)
# Creamos el gráfico de dispersión (scatter plot)
grafico_obj1 <- ggplot(datos_finales_obj1, aes(x = Porcentaje_Teletrabajo_Ocupados, y = Porcentaje_Con_Depresion)) +
  geom_point(aes(color = Comunidad), size = 4) + # Puntos coloreados por CCAA
  geom_smooth(method = "lm", se = TRUE, color = "#1f77b4", linetype = "dashed") + # Línea de tendencia (LM)
  labs(
    title = "Relación entre Teletrabajo y Depresión por Comunidad Autónoma",
    subtitle = "El eje X es el % de trabajadores que teletrabajan. El eje Y es el % de población con depresión.",
    x = "Población que Teletrabaja (% de Ocupados)",
    y = "Población con Episodios Depresivos (%)",
    color = "Comunidad"
  ) +
  theme_minimal() +
  theme(legend.position = "bottom")

# Convertimos a interactivo para ver los nombres de las CCAA al pasar el ratón
ggplotly(grafico_obj1)

Relacion entre teletrabajo y salud mental en las Islas Canarias

# 1. FILTRO: Obtenemos el indicador de ALTO RIESGO de salud mental por Isla
salud_mental_riesgo <- salud_mental_final %>%
  filter(Estado_Mental == "6 o más") %>%
  select(Isla, Porcentaje_Riesgo = Porcentaje) # Renombramos la columna Valor a Porcentaje_Riesgo

# 2. UNIÓN: Cruzamos el riesgo de salud mental con el porcentaje de teletrabajo
datos_canarias_final <- left_join(teletrabajo_personal_canarias, salud_mental_riesgo, by = "Isla")

# 3. VISUALIZACIÓN: Scatter plot para ver la correlación en ambas provincias

grafico_obj2 <- ggplot(datos_canarias_final, aes(x = Porcentaje_Personal_Teletrabajador, y = Porcentaje_Riesgo)) +
  geom_point(aes(color = Isla, text = paste("Isla:", Isla, "<br>Riesgo:", Porcentaje_Riesgo, "%")), size = 5) + # Usamos text para el tooltip de plotly
  geom_smooth(method = "lm", se = FALSE, color = "gray", linetype = "dotted") +
  
  # Usamos facet_wrap para separar el análisis por provincia
  facet_wrap(~ Provincia, scales = "free") +
  
  labs(
    title = "Teletrabajo vs. Riesgo de Problemas de Salud Mental en Canarias",
    subtitle = "El eje Y es el porcentaje de población con 6 o más síntomas (alto riesgo).",
    x = "Personal Teletrabajador (%)",
    y = "Población con Alto Riesgo Mental (%)"
  ) +
  theme_minimal() +
  theme(legend.position = "none")

# Convertimos a interactivo para ver los detalles
ggplotly(grafico_obj2, tooltip = "text")